package com.jwmp.rbac.service.impl;


import com.jwmp.core.util.PageResult;
import com.jwmp.core.util.QueryObject;
import com.jwmp.rbac.domain.Module;
import com.jwmp.rbac.domain.Permission;
import com.jwmp.rbac.mapper.PermissionMapper;
import com.jwmp.rbac.service.IModuleService;
import com.jwmp.rbac.service.IPermissionService;
import com.jwmp.core.util.MyBatisUtil;
import com.jwmp.rbac.util.PermissionUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PermissionServiceImpl implements IPermissionService {
    private IModuleService moduleService = new ModuleServiceImpl();

    /**
     * 加载权限到数据库中，只加入新的，旧的不重新加入
     * @param loadPermissionPackageName
     */
    public void loadPremissionToDB(String loadPermissionPackageName){
        // 1 查询数据库中模块列表
        Map<String,List<Module>> dbModuleMap = moduleService.selectBaseList().stream().collect(Collectors.groupingBy(Module :: getName));
        // 2 查询数据库中权限列表
        Map<String,List<Permission>> dbPermissionMap = this.selectBaseList().stream().collect(Collectors.groupingBy(Permission :: getExpression));

        // 3 获取项目中所有的权限列表
        List<Permission> projectPermissionList = PermissionUtil.loadPremissionToList(loadPermissionPackageName);

        // 4 插入新模块和新权限
        // 4.1 筛选出项目权限列表中新的权限并转为 map 集合
        Map<String, List<Permission>> newPermissionMap = projectPermissionList.stream()
                .filter(userPermission -> !dbPermissionMap.containsKey(userPermission.getExpression()))   // 筛选出数据库没有的权限
                .collect(Collectors.groupingBy(p -> p.getModule().getName()));                            // 转为 map ，key 为模块名
        // 4.2 筛选出新的 Module，加入 Module 表中，旧的 Module ，加入 id 到 Perssion 中
        newPermissionMap.forEach((moduleName,permissionList) -> {
            if ( ! dbModuleMap.containsKey(moduleName) ) {
                // 模块不存在，先插入模块再插入权限
                Long moduleId = moduleService.insert(new Module(moduleName));
                // 插入权限
                this.insertBath(moduleId,permissionList);
            }else{
                // 通过模块名称到查询出来的模块map 中获取模块的id
                this.insertBath(dbModuleMap.get(moduleName).get(0).getId(),permissionList);
            }
        });
    }

    public void insertBath(Long moduleId,List<Permission> list) {
        SqlSession session = MyBatisUtil.openSession();
        PermissionMapper permissionMapper = session.getMapper(PermissionMapper.class);
        permissionMapper.insertBath(moduleId,list);
        session.commit();
        session.close();
    }

    public List<Permission> selectBaseList() {
        SqlSession session = MyBatisUtil.openSession();
        PermissionMapper permissionMapper = session.getMapper(PermissionMapper.class);
        List<Permission> list = permissionMapper.selectBaseList();
        session.close();
        return list;
    }

    public PageResult queryList(QueryObject qo) {
        SqlSession session = MyBatisUtil.openSession();
        PermissionMapper permissionMapper = session.getMapper(PermissionMapper.class);
        int totalCount = permissionMapper.selectCount(qo);
        if (totalCount == 0) {
            session.close();
            return new PageResult(qo.getCurrentPage(),qo.getPageSize());
        }
        List<Permission> permissionList = permissionMapper.selectList(qo);
        session.close();
        return new PageResult(qo.getCurrentPage(),qo.getPageSize(),permissionList,totalCount);
    }

    public List<Permission> selectByRoleId(Long roleId) {
        SqlSession session = MyBatisUtil.openSession();
        PermissionMapper permissionMapper = session.getMapper(PermissionMapper.class);
        List<Permission> plist = permissionMapper.selectByRoleId(roleId);
        session.close();
        return plist;
    }

    public void authorizeForRole(Long roleId, List<Long> permissionIdList) {
        // 获取该角色下所有权限
        List<Long> existIdList = selectByRoleId(roleId).stream().map(p ->  p.getId()).collect(Collectors.toList());
        // 筛选出新的权限进行授权发射 ==>  ==>
        List<Long> newIdList = permissionIdList.stream()
                                            .filter(pId -> !existIdList.contains(pId)).collect(Collectors.toList());
        // 筛选出本来有的，本地修改删除的
        List<Long> delIdList = existIdList.stream()
                                            .filter(pId -> !permissionIdList.contains(pId)).collect(Collectors.toList());
        SqlSession session = MyBatisUtil.openSession();
        PermissionMapper permissionMapper = session.getMapper(PermissionMapper.class);
        if (newIdList.size() > 0) {
            permissionMapper.authorizeForRole(roleId,newIdList);
        }
        if (delIdList.size() > 0) {
            permissionMapper.deleteBath(roleId,delIdList);
        }

        session.commit();
        session.close();

    }

    public List<Permission> selectListByEmpId(Long empId) {
        SqlSession session = MyBatisUtil.openSession();
        PermissionMapper permissionMapper = session.getMapper(PermissionMapper.class);
        List<Permission> permissionList = permissionMapper.selectListByEmpId(empId);
        session.commit();
        session.close();
        return permissionList;
    }
}
